package com.dy.yunying.biz.controller.sign;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dy.yunying.api.dto.hongbao.HbInvitationTopDto;
import com.dy.yunying.api.dto.sign.SignActivityPrizeDto;
import com.dy.yunying.api.entity.hongbao.HbGiftBag;
import com.dy.yunying.api.entity.hongbao.HbInvitationTop;
import com.dy.yunying.api.entity.sign.*;
import com.dy.yunying.api.utils.CheckUtils;
import com.dy.yunying.api.vo.sign.GoodsVO;
import com.dy.yunying.biz.service.hongbao.HbGiftBagService;
import com.dy.yunying.biz.service.sign.*;
import com.google.common.collect.Lists;
import com.pig4cloud.pig.common.core.constant.CommonConstants;
import com.pig4cloud.pig.common.core.util.CommonUtils;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.log.annotation.SysLog;
import com.pig4cloud.pig.common.security.service.PigUser;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * 签到活动奖品表
 * @author  chengang
 * @version  2021-12-01 10:14:16
 * table: sign_activity_prize
 */
@RestController
@RequestMapping("/prize")
@RequiredArgsConstructor
public class SignActivityPrizeController {
	
    private final SignActivityPrizeService signActivityPrizeService;
    private final SignActivityGoodsService signActivityGoodsService;
    private final SignPrizeGoodsService signPrizeGoodsService;
    private final SignReceiveRecordService signReceiveRecordService;
    private final HbGiftBagService hbGiftBagService;
    private final SignActivityService signActivityService;


	@PreAuthorize("@pms.hasPermission('ACTIVITY_PRIZE_LIST')")
	@GetMapping("/list")
	public R<Page<SignActivityPrize>> getList(SignActivityPrizeDto record) {
		if (record.getActivityId() == null) {
			return R.failed("活动ID不能为空");
		}
		final Page<SignActivityPrize> page = signActivityPrizeService.getPage(record);
		return R.ok(page);
	}


	@SysLog("编辑奖品")
	@RequestMapping("/edit")
	public R editPrize(SignActivityPrizeDto dto){
		R check = this.baseCheck(dto);
		if (check.getCode() == CommonConstants.FAIL) {
			return check;
		}
		PigUser user = SecurityUtils.getUser();
		dto.setCreateId(user.getId().longValue());
		dto.setUpdateId(user.getId().longValue());
		return signActivityPrizeService.editPrize(dto);
	}


	@GetMapping("/getInfo")
	public R getPrizeInfo(Long id){
		if (id == null) {
			return R.failed("主键ID不能为空");
		}
		SignActivityPrize prizeInfo = signActivityPrizeService.getById(id);
		List<GoodsVO> goodsVOList = Lists.newArrayList();
		List<SignPrizeGoods> prizeGoods = signPrizeGoodsService.list(Wrappers.<SignPrizeGoods>lambdaQuery()
				.eq(SignPrizeGoods::getDeleted,0)
				.in(SignPrizeGoods::getPrizeId,id));
		if (CollectionUtils.isNotEmpty(prizeGoods)) {
			prizeGoods.forEach(pg -> {
				GoodsVO goodsVO = new GoodsVO();
				goodsVO.setGoodsId(pg.getGoodsId());
				goodsVO.setGoodsCount(pg.getNum());

				goodsVOList.add(goodsVO);

			});
			prizeInfo.setGoodsList(goodsVOList);
		}
		SignActivity activity = signActivityService.getById(prizeInfo.getActivityId());
		if (activity != null) {
			prizeInfo.setActivityStatus(activity.getActivityStatus());
		}
		return R.ok(prizeInfo);
	}


	@GetMapping("/getGoodsList")
	public R getGoodsList(String name){
		List<SignActivityGoods> goodsList = signActivityGoodsService.list(Wrappers.<SignActivityGoods>lambdaQuery()
				.eq(SignActivityGoods::getDeleted,0)
				.and(StringUtils.isNotBlank(name),wrapper -> wrapper.like(SignActivityGoods::getName,name)));
		return R.ok(goodsList);
	}


	private R baseCheck(SignActivityPrizeDto dto){
		if (dto.getId() == null) {
			return R.failed("主键ID不能为空");
		}
		if (StringUtils.isBlank(dto.getName())) {
			return R.failed("奖品名称不能为空");
		}

		if (dto.getName().trim().length()>16) {
			return R.failed("奖品名称长度不能超过16");
		}

		if (dto.getType() == null) {
			return R.failed("奖品类型不能为空");
		}

		SignActivityPrize prize = signActivityPrizeService.getById(dto.getId());

		//奖品名称不能重复
		List<SignActivityPrize> list = signActivityPrizeService.list(Wrappers.<SignActivityPrize>lambdaQuery()
				.eq(SignActivityPrize::getActivityId, prize.getActivityId())
				.eq(SignActivityPrize::getDeleted, 0)
				.and(wrapper -> wrapper.eq(SignActivityPrize::getName, dto.getName()))
				.and(dto.getId() != null, wrapper -> wrapper.ne(SignActivityPrize::getId, dto.getId())));
		if (CollectionUtils.isNotEmpty(list)) {
			return R.failed("奖品名称不能重复");
		}
		if (dto.getType() == 1) {
			if (StringUtils.isBlank(dto.getGoodsJson())) {
				return R.failed("奖品内容不能为空");
			}
			List<GoodsVO> goodsList = JSON.parseArray(dto.getGoodsJson(),GoodsVO.class);
			if (CollectionUtils.isEmpty(goodsList)) {
				return R.failed("奖品内容不能为空");
			}
			List<Long> goodsIds = goodsList.stream().map(GoodsVO::getGoodsId).distinct().collect(Collectors.toList());
			if (goodsIds.size() != goodsList.size()) {
				return R.failed("奖品内容不能添加相同的物品");
			}

			if (StringUtils.isBlank(dto.getGiftType())){
				return R.failed("请选择礼包码类型");
			}
			// 礼包唯一码
			if ("1".equals(dto.getGiftType())){
				if (dto.getFile() == null) {
					return R.failed("礼包码不能为空");
				}
				// 获取名称
				String filename = dto.getFile().getOriginalFilename();
				// 获取后缀名
				String suffix = filename.substring(filename.lastIndexOf(".") + 1);
				if (!"TXT".equals(suffix.toUpperCase())) {
					return R.failed("礼包码文件仅支持txt格式");
				}
				Long size = dto.getFile().getSize();
				if (size < 3 || size > 1048576){
					return R.failed("礼包码文件大小应在3字节~1M之间");
				}
				//校验物品数量-暂时前端校验
			}else if("2".equals(dto.getGiftType())){
			// 礼包通用码
				String giftAmount = dto.getGiftAmount();
				String giftCode = dto.getGiftCode();
				if (StringUtils.isBlank(giftCode)){
					return R.failed("请输入通用礼包码");
				}
				if (StringUtils.isBlank(giftAmount)){
					return R.failed("请输入礼包码数量");
				}
				String regex = "^[A-Za-z0-9]+$";
				if (giftCode.length() < 3 || giftCode.length() > 50 || !giftCode.matches(regex)){
					return R.failed("通用礼包码应为3~50个英文大小写或数字组成");
				}
				if (!CheckUtils.checkInt(giftAmount)){
					return R.failed("请输入有效的礼包数量");
				}
				if (giftAmount.length() > 7 || Integer.valueOf(giftAmount) < 0 || Integer.valueOf(giftAmount) > 9999999){
					return R.failed("礼包数量应为0~9999999");
				}
			}
		} else if (dto.getType() == 2 ) {
			if (StringUtils.isBlank(dto.getCdkName())) {
				return R.failed("代金券名称不能为空");
			}
			if (dto.getCdkName().trim().length()>16) {
				return R.failed("代金券名称长度不能超过16");
			}

			if (StringUtils.isBlank(dto.getCdkAmount())) {
				return R.failed("代金券金额不能为空");
			}

			if (!CommonUtils.isMoney(dto.getCdkAmount(),0)) {
				return R.failed("代金券金额格式不正确");
			}

			if (dto.getCdkAmount().trim().length() > 6) {
				return R.failed("代金券金额长度不能超过6位");
			}

			if (StringUtils.isBlank(dto.getCdkLimitAmount())) {
				return R.failed("满可用金额不能为空");
			}

			if (!CommonUtils.isMoney(dto.getCdkLimitAmount(),0)) {
				return R.failed("满可用金额格式不正确");
			}

			if (dto.getCdkLimitAmount().trim().length() > 6) {
				return R.failed("满可用金额长度不能超过6位");
			}

			BigDecimal cdkAmount = new BigDecimal(dto.getCdkAmount());
			BigDecimal cdkLimitAmount = new BigDecimal(dto.getCdkLimitAmount());
			if (cdkLimitAmount.compareTo(cdkAmount) <=0) {
				return R.failed("满可用金额必须大于代金券金额");
			}

			if (dto.getExpiryType() == null) {
				return R.failed("有效规则不能为空");
			}

			if (dto.getExpiryType() == 1) {
				if (StringUtils.isBlank(dto.getStartTime())) {
					return R.failed("开始时间不能为空");
				}
				if (StringUtils.isBlank(dto.getEndTime())) {
					return R.failed("结束时间不能为空");
				}
				//校验开始时间 >= 领取时间
				Date sDate = DateUtil.parse(dto.getStartTime(),"yyyy-MM-dd");
				Date eDate = DateUtil.parse(dto.getEndTime(),"yyyy-MM-dd");
				if (sDate.compareTo(prize.getReceiveDate()) < 0) {
					return R.failed("开始时间不能小于签到时间"+DateUtil.format(prize.getReceiveDate(),"yyyy-MM-dd"));
				}

				if (eDate.compareTo(sDate) < 0) {
					return R.failed("结束时间不能小于开始时间");
				}

			}


			if (dto.getExpiryType() == 2 && dto.getDays() == null) {
				return R.failed("有效天数不能为空");
			}
			if (null == dto.getCdkLimitType()) {
				return R.failed("代金券限制类型不能为空");
			}

		} else if (dto.getType() == 3) {
			final BigDecimal amount = dto.getCurrencyAmount();
			if (null == amount || amount.compareTo(BigDecimal.ZERO) < 0) {
				return R.failed("请提供余额金额，并且金额不能小于0");
			}
			final Integer currencyType = dto.getCurrencyType();
			if (null == currencyType) {
				return R.failed("请提供余额类型");
			} else if (1 == currencyType) {
			} else if (2 == currencyType) {
				final Integer expireType = dto.getCurrencyExpireType();
				if (null == expireType) {
					return R.failed("请提供余额过期类型");
				} else if (1 == expireType) {
					final Date expireTime = dto.getCurrencyExpireTime();
					final Date receiveDate = prize.getReceiveDate();
					if (null == expireTime || expireTime.before(receiveDate)) {
						return R.failed("请提供正确的余额过期时间，并且过期时间不能小于签到时间" + DateUtil.format(prize.getReceiveDate(), "yyyy-MM-dd"));
					}
				} else if (2 == expireType) {
					final Integer expireDays = dto.getCurrencyExpireDays();
					if (null == expireDays || expireDays < 0) {
						return R.failed("请提供正确的余额过期天数，并且过期天数不能为空");
					}
				} else {
					return R.failed("未知的余额过期类型");
				}
			} else {
				return R.failed("未知的余额类型");
			}
		}

		return R.ok();
	}
}


